package com.blog.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.bo.BlogArticleBO;
import com.blog.entity.BlogArticle;
import com.blog.entity.BlogManager;
import com.blog.service.ArticleService;
import com.blog.utils.BusinessException;

import com.blog.utils.ConstUtil;
import com.blog.vo.TimeLineVo;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Huangzp
 * @Date 2021/12/15 14:47
 */
@Service
@Transactional(rollbackFor = BusinessException.class)
public class ArticleServiceImpl implements ArticleService {


    @Autowired
    private BlogArticleBO blogArticleBO;


    @Override
    public List<BlogArticle> getArticleList(String keywords, Integer currentPage, Integer pageSize) {
        LambdaQueryWrapper<BlogArticle> blogArticleWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(keywords)) {
            blogArticleWrapper.like(BlogArticle::getArticleTag,keywords)
                    .or().like(BlogArticle::getArticleRemark,keywords)
                    .or().like(BlogArticle::getArticleContent,keywords)
                    .or().like(BlogArticle::getArticleName,keywords)
                    .or().like(BlogArticle::getManagerName,keywords);
        }
        Page<BlogArticle> blogArticlePage = new Page<>(currentPage,pageSize);
        IPage<BlogArticle> blogArticleIPage =blogArticleBO.page(blogArticlePage,blogArticleWrapper);
        return blogArticleIPage.getRecords();
    }

    @Override
    public void updateArticle(BlogArticle article) {
        try {
            BlogManager manager = (BlogManager) SecurityUtils.getSubject().getPrincipal();
            if(manager == null){
                throw new BusinessException("当前用户未登录");
            }else{
                article.setManagerName(manager.getName());
            }

            //验证文章
            QueryWrapper<BlogArticle> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(BlogArticle::getArticleName,article.getArticleName())
                    .ne(article.getId() != null,BlogArticle::getId,article.getId());
            int count = blogArticleBO.count(queryWrapper);
            if (count>0){
                throw new  BusinessException("存在相同题目的文章");
            }
            if (null != article.getId()){
                //修改
                blogArticleBO.updateById(article);
            }else {
                //添加
                blogArticleBO.save(article);
            }
            /*if (ConstUtil.ARTICLE_ID != article.getId()){
                //把数据存入索引中，文章id为1时是介绍自己
                articleRepository.save(article);
            }*/
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        }
    }

    @Override
    public void deleteArticle(List<Integer> ids) {
        try {
            if(ids.contains(ConstUtil.ARTICLE_ID)){
                throw new  BusinessException("自我介绍不能删除");
            }
            List<BlogArticle> articles = blogArticleBO.listByIds(ids);
            //删除索引
            //articleRepository.deleteAll(articles);
            //删除文章
            blogArticleBO.removeByIds(ids);
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        }
    }

    @Override
    public List<BlogArticle> getArticleByPage(BlogArticle article) {
        QueryWrapper<BlogArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(null!=article.getArticleType(),BlogArticle::getArticleType,article.getArticleType())
                .like(StringUtils.isNotBlank(article.getArticleName()), BlogArticle::getArticleName, article.getArticleName())
                .ne(BlogArticle::getId, ConstUtil.ARTICLE_ID)
                .orderByDesc(article.isRecommend(),BlogArticle::getArticleReadCount)
                .orderByDesc(article.isFavorite(),BlogArticle::getArticleStarNum)
                .orderByDesc(article.isCommentMost(),BlogArticle::getArticleConNum)
                .orderByDesc(BlogArticle::getCreateTime);
        return blogArticleBO.list(queryWrapper);
    }

    @Override
    public BlogArticle searchById(int id) {
        BlogArticle article = blogArticleBO.getById(id);
        //阅读量加一
        article.setArticleReadCount(article.getArticleReadCount()+1);
        blogArticleBO.updateById(article);
        return article;
    }

    @Override
    public BlogArticle searchByArticleIdAndManagerId(int articleId, int managerId) {
        QueryWrapper<BlogArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BlogArticle::getId,articleId)
                .eq(BlogArticle::getManagerId,managerId)
                .eq(BlogArticle::getArticleState,ConstUtil.OTHER_STATE);
        BlogArticle article = blogArticleBO.getOne(queryWrapper);
        BlogManager manager = (BlogManager) SecurityUtils.getSubject().getPrincipal();
        if(!manager.getId().equals(article.getManagerId())){
            throw new BusinessException("当前登录人和文章博主不一致");
        }

        return article;
    }

    @Override
    public List<String> searchTag() {
        List<String> tags = blogArticleBO.searchTag();
        List<String> articleTags = new ArrayList<>();
        for(String str:tags){
            ArrayList<String> strings = Lists.newArrayList(str.split(","));
            articleTags.addAll(strings);
        }
        //去重
        return articleTags.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public List<TimeLineVo> searchTimeLine() {
        List<BlogArticle> articles = blogArticleBO.searchTimeLine();
        List<TimeLineVo> lineVos = new ArrayList<>();
        //取出时间
        List<String> yearTimesList = articles.stream().map(BlogArticle::getCreateTime).collect(Collectors.toList());
        //时间转换为年份
        List<Integer> years = yearTimesList.stream().map(x -> DateUtil.year(DateUtil.parse(x))).collect(Collectors.toList());
        //年份去重
        List<Integer> collect = years.stream().distinct().collect(Collectors.toList());
        for (Integer yearTimes : collect){
            TimeLineVo timeLineVo = new TimeLineVo();
            //对文章集合中的时间与年份匹配
            List<BlogArticle> articleList = articles.stream().filter(item -> item.getCreateTime().contains(yearTimes.toString())).collect(Collectors.toList());
            timeLineVo.setYear(yearTimes.toString());
            timeLineVo.setArticle(articleList);
            lineVos.add(timeLineVo);
        }
        return lineVos;
    }
}
